﻿module Sustainalytics.Portfolio {


    import Common = Sustainalytics.Common;
    import SearchPortfolio = Sustainalytics.Portfolio.PortfolioSearchController;
    import Portfolio = Sustainalytics.Portfolio;
    import LRTM = Sustainalytics.LRTM;

    // Portfolio List controller
    export class PortfolioUploadController {

        public portfolio: PortfolioDto;
        public portfolioFilter: PortfolioFilterDto;
        public isShared: boolean;
        public portfolioSearch: string;
        private accountId: string;
        private userId: string;
        private selectedFile: File;
        private portfolioUpload: PortfolioUploadDto;
        public isIe9: boolean;
        private lrtmservice: LRTM.LongRunningTaskManagerService;

        // Ctor.
        constructor(
            private $rootScope: ng.IScope,
            private $scope: ng.IScope,
            private $q: ng.IQService,
            private $http: ng.IHttpProvider,
            private $location: ng.ILocationService,
            private PortfolioService: PortfolioService,
            private PortfolioCompanyService: PortfolioCompanyService,
            private notificationFactory: Common.INotificationFactory,
            private staticObjects: Common.IStaticObjects,
            private $modal: Common.IModal,
            private $modalInstance: Common.IModalInstance,
            private LongRunningTaskManagerService: LRTM.LongRunningTaskManagerService,
            private listPortfoliosHandler) {

            var ctx = this;
            ctx.isShared = false;
            ctx.portfolio = new PortfolioDto();
            ctx.portfolioFilter = new PortfolioFilterDto();
            ctx.portfolioFilter.isMyPortfolio = true;
            ctx.portfolioFilter.isNameEqual = true;
            ctx.portfolioFilter.sharingStatus = ctx.isShared ? PortfolioSharingStatus.Shared : PortfolioSharingStatus.Private;
            ctx.portfolioUpload = new PortfolioUploadDto();
            ctx.portfolioSearch = "";

            if (ctx.$rootScope['userInfo'] == null) {
                ctx.$rootScope['userInfo'] = angular.fromJson(localStorage.getItem('sust_userInfo'));
            }
            ctx.accountId = ctx.$rootScope['userInfo'].accountId;
            ctx.userId = ctx.$rootScope['userInfo'].userId;
            ctx.portfolioUpload.accountId = ctx.accountId;
            ctx.portfolioUpload.userId = ctx.userId;
            this.lrtmservice = LongRunningTaskManagerService;




            $scope['portfolioAdd'] = ctx;
            ctx.isIe9 = navigator.appVersion.indexOf("MSIE 9.") != -1;

        }

        public cancel = function (newStatus) {

            var ctx = this;
            ctx.$rootScope['loading'] = false;
            ctx.$modalInstance.close({ newStatus: newStatus });
            if (ctx.isIe9) {
                $('#testHack').attr('action', "");
            }

        };

        public initData() {
            doIe9HackForInputFile(this.isIe9);
        }

        public selectPortfolioAdd(item) {
            var ctx = this;
            ctx.portfolio.name = item.name;
            ctx.portfolio.id = item.id;
            ctx.portfolioFilter.namePortfolio = item.name;
            ctx.portfolioFilter.portfolioId = item.name;
        }

        public downloadPortfolioUploadTemplate() {
            var ctx = this;
            var promise = ctx.LongRunningTaskManagerService.runTask('Download securities template ', null, LRTM.LongRunningTaskTypeEnum.PortfolioSecuritiesDownloadTemplate, true, null);
        }

        private showErrorCode(code: number) {
            var ctx = this;
            var msg = ctx.staticObjects.getErrorMesageByStatusCode(code);
            ctx.notificationFactory.error('', msg);
        }

        public onSelectExcel($files): any {
            var ctx = this;
            ctx.selectedFile = null;
            var file = $files[0]; // html assures is just 1
            if (file && (file.type != "application/vnd.ms-excel" && file.type != "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")) {
                ctx.showErrorCode(5210);
            }
            else if (file) {
                ctx.selectedFile = file;
            }
        }

        private getPortfolioThatsOverwritten(response: PortfolioListDto): PortfolioDto {
            if (response["count"] === 0) return null;

            var portfolios = response["portfolios"];
            var filtered = portfolios.filter(portfolio => (portfolio.addedByUserId === this.userId || portfolio.isSystemPortfolio));
            if (filtered.length > 0)
            { return filtered[0]; }
            return null;
        }

        public savePortfolioFromUpload() {

            var ctx = this;
            ctx.setUrlFormForIe9();
            var files = $('#portfolioFile').get(0)['files'];
            ctx.portfolioFilter.namePortfolio = ctx.portfolioSearch;
            ctx.portfolioFilter.isNameEqual = true;

            var fileDefined = false;
            if (files != undefined && files.length > 0) {
                fileDefined = true;
            }
            if (files == undefined && $('#portfolioFile').val() != undefined && $('#portfolioFile').val() != "") {
                fileDefined = true;
                files = [$('#portfolioFile').val()];
            }

            var tempFilter: PortfolioFilterDto = new PortfolioFilterDto();
            tempFilter.portfolioType = PortfolioTypes.All;
            tempFilter.namePortfolio = this.portfolioSearch;
            tempFilter.isNameEqual = true;
            tempFilter.sharingStatus = PortfolioSharingStatus.All;

            if (fileDefined && ctx.portfolioSearch.length > 0) {
                var promiseCount: ng.IPromise<PortfolioListDto> = ctx.PortfolioService.getPortfolioCount(tempFilter, ctx.accountId, ctx.userId);

                promiseCount.then(response => {

                    var currentPortfolio: PortfolioDto = this.getPortfolioThatsOverwritten(response);

                    if (currentPortfolio != null) {
                        if (currentPortfolio.isSystemPortfolio) {
                            this.notificationFactory.error("", "A portfolio with this name already exists!");
                        }
                        else {
                            var modalInstancePortfolio = this.$modal.open({
                                templateUrl: 'Views/Portfolio/portfolioExists_dialog.tpl.html',
                                controller: 'PortfolioCheckController',
                                size: 'lg',
                                backdrop: 'static',
                                resolve: {
                                    message() {
                                        return "Are you sure you want to overwrite the existing Portfolio?";
                                    },
                                    informationMessage() {
                                    }
                                }
                            });

                            modalInstancePortfolio.result.then(out => {
                                if (out["portfolioCheck"] === true) {
                                    if (this.isIe9) {
                                        this.hackActionForm(currentPortfolio.id, currentPortfolio.name);
                                    } else {
                                        var promise = this.doTaskUpload(currentPortfolio.id, currentPortfolio.name, 'Upload portfolio ', files);

                                        promise.finally(() => {

                                            ga('create', 'UA-4379897-6', {
                                                'userId': this.userId,
                                                'cookieDomain': 'none',
                                                'name': 'globalAccess'
                                            });

                                            ga('globalAccess.set', 'dimension1', this.userId);

                                            var dateNow = new Date();
                                            var dateNowString = [dateNow.getDate(), dateNow.getMonth() + 1, dateNow.getFullYear()].join("/");
                                            var gaObject: any = {
                                                Date: dateNowString,
                                                AccountId: this.accountId,
                                                UserId: this.userId
                                            };

                                            ga('globalAccess.send', {
                                                'hitType': 'event',
                                                'eventCategory': 'Portfolio Management',
                                                'eventAction': 'AddPortfolio',
                                                'eventLabel': JSON.stringify(gaObject)
                                            });
                                        });
                                    }
                                } else {
                                    var element = document.getElementById("portfolioAddSearchInput");
                                    if (element)
                                        element.focus();
                                }
                            });
                        }
                    }
                    else {

                        if (this.isIe9) {

                            this.hackActionForm(this.portfolio.id, this.portfolioSearch);
                        } else {
                            var promise = this.doTaskUpload(this.portfolio.id, this.portfolioSearch, 'Upload task ', files);
                            promise.catch((error) => {
                                if (error) {
                                    ctx.notificationFactory.error('', ctx.staticObjects.getErrorMesageByStatusCode(error));
                                }
                                ctx.notificationFactory.error('', ctx.staticObjects.getErrorMesageByStatusCode());
                                this.$rootScope['loading'] = false;
                            });
                        }

                        ga('create', 'UA-4379897-6', {
                            'userId': this.userId,
                            'cookieDomain': 'none',
                            'name': 'globalAccess'
                        });

                        ga('globalAccess.set', 'dimension1', this.userId);

                        var dateNow = new Date();
                        var dateNowString = [dateNow.getDate(), dateNow.getMonth() + 1, dateNow.getFullYear()].join("/");
                        var gaObject: any = {
                            Date: dateNowString,
                            AccountId: this.accountId,
                            UserId: this.userId
                        };

                        ga('globalAccess.send', {
                            'hitType': 'event',
                            'eventCategory': 'Portfolio Management',
                            'eventAction': 'AddPortfolio',
                            'eventLabel': JSON.stringify(gaObject)
                        });

                    }
                });
            }
            else {
                if (files.length == 0)
                    ctx.showErrorCode(5203);
                if (ctx.portfolioSearch.length == 0)
                    ctx.showErrorCode(5010);
                ctx.$rootScope['loading'] = false;
            }
        }

        public doTaskUpload(portfolioId: string, portfolioName: string, taskTitle: string, files: any[]): ng.IPromise<string> {
            var ctx = this;

            ctx.$rootScope['loading'] = true;
            

            ctx.portfolioUpload.portfolioId = portfolioId;
            ctx.portfolioUpload.portfolioName = portfolioName;
            ctx.portfolioUpload.sharingStatus = ctx.isShared ? PortfolioSharingStatus.Shared : PortfolioSharingStatus.Private;

            var now = new Date();
            var now_utc = new Date(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate(), now.getUTCHours(), now.getUTCMinutes(), now.getUTCSeconds());
            ctx.portfolioUpload.insertDate = now_utc;

            var promise = ctx.LongRunningTaskManagerService.runTaskWithUpload(
                taskTitle, // title
                JSON.stringify(ctx.portfolioUpload), // paramJson
                Sustainalytics.LRTM.LongRunningTaskTypeEnum.PortfolioSecuritiesUpload, // taskType
                files, // files
                null, // uploadProgressFunc
                false, // isDownload
                (taskInstanceId, newStatus, oldStatus, taskInstance) => ctx.statusChangedCallback(taskInstanceId, portfolioId, newStatus, oldStatus, taskInstance) // statusChangedCallback
            );
            return promise;
        }


        public hackActionForm(portfolioId: string, portfolioName: string) {
            var ctx = this;
            addFormForIe9Hack(ctx.isIe9);
            ctx.$rootScope['loading'] = true;
            var uploadDto = new PortfolioUploadDto();
            uploadDto.accountId = ctx.$rootScope['userInfo'].accountId;
            uploadDto.userId = ctx.$rootScope['userInfo'].userId;
            uploadDto.portfolioName = ctx.portfolioSearch;
            uploadDto.sharingStatus = ctx.isShared ? PortfolioSharingStatus.Shared : PortfolioSharingStatus.Private;
            uploadDto.portfolioId = portfolioId;
            // document.cookie = "Authorization:Bearer " + ctx.$rootScope['authData']['access_token'];
            //var oauth = ctx.$rootScope['authData']['access_token'];
            var uploadStr = JSON.stringify(uploadDto);
            var now = new Date();
            //  ctx.$http.defaults.headers.common["Authorization"] = 'Bearer ' + oauth;
            uploadDto.insertDate = new Date(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate(), now.getUTCHours(), now.getUTCMinutes(), now.getUTCSeconds());
            var taskInstances = ctx.lrtmservice.getTaskInstances();
            var lastOrder = taskInstances.length > 0 ? taskInstances[taskInstances.length - 1].status.order : 0;
            var instance: LRTM.LongRunningTaskInstance;
            instance = LRTM.LongRunningTaskInstance.createVirtual(ctx.LongRunningTaskManagerService.generateUUID(), 'Upload task ', LRTM.LongRunningTaskTypeEnum.PortfolioSecuritiesUpload, lastOrder + 1, true, true);
            instance.statusChangedCallback = (taskInstanceId, newStatus, oldStatus, taskInstance) => ctx.statusChangedCallback(taskInstanceId, portfolioId, newStatus, oldStatus, taskInstance);
            ctx.lrtmservice.addAlreadyCreateTaskInstance(instance);
            var postData =
                {
                    id: instance.status.id,
                    title: instance.status.title,
                    paramJson: uploadStr,
                    taskType: LRTM.LongRunningTaskTypeEnum.PortfolioSecuritiesUpload,
                    fileName: $('#inputFile').val(),
                    mimeType: null,
                    isUpload: true,
                    isDownload: true,
                    order: lastOrder + 1
                };
            var jsonStringify = JSON.stringify(postData);
            $('#jsonData').val(jsonStringify);
            ctx.setUrlFormForIe9();
            $('#testHack').submit();
        }

        private setUrlFormForIe9() {
            var ctx = this;
            if (!ctx.isIe9) return;
            var oauth = ctx.$rootScope['authData']['access_token'];
            var encod = encodeURIComponent(oauth);
            var url = "/lrtmserv/api/v1/task?oauth=" + encod;
            $('#testHack').attr('action', url);

        }


        public statusChangedCallback(taskInstanceId: string, portfolioId, newStatus: LRTM.LongRunningTaskInstanceStatusEnum, oldStatus: LRTM.LongRunningTaskInstanceStatusEnum, taskInstance: LRTM.LongRunningTaskInstance): void {
            var ctx = this;
            if (newStatus === LRTM.LongRunningTaskInstanceStatusEnum.Failed) {
                var promise = ctx.LongRunningTaskManagerService.getResult(taskInstanceId, false);
                promise.then(function (res) {
                    ctx.$rootScope['loading'] = false;
                    var serverErrors = taskInstance.status.taskStatus.errors;
                    if (serverErrors && serverErrors.length > 0) {

                        serverErrors.forEach(serverErr => {
                            taskInstance.errors.push(serverErr.arguments[0]);
                        });
                    }
                });
            }


            // display result
            if (newStatus == LRTM.LongRunningTaskInstanceStatusEnum.Finished) {
                var promise = ctx.LongRunningTaskManagerService.getResult(taskInstanceId, false);
                promise.then(function (res) {
                    
                    if (taskInstance.status.taskStatus.details && taskInstance.status.taskStatus.details.length > 0) {
                        ctx.$rootScope['loading'] = false;
                        var i = setInterval(function () {
                            // do your thing
                            console.log(taskInstance.status.taskInstanceStatus);

                            if (taskInstance.status.taskInstanceStatus === LRTM.LongRunningTaskInstanceStatusEnum.Finished) {
                                ctx.LongRunningTaskManagerService.deleteTask(taskInstanceId);
                                clearInterval(i);
                            }
                        }, 1000);

                        ctx.cancel(newStatus);
                        var modalInstanceErrors = ctx.$modal.open(
                            {
                                templateUrl: '/Views/Portfolio/portfolioMatches_dialog.tpl.html',
                                controller: 'PortfolioMatchesModalController',
                                size: 'lg',
                                backdrop: 'static',
                                keyboard: false,
                                resolve:
                                {
                                    portfolioId: function () {
                                        return portfolioId;
                                    },
                                    portfolioName: function () {
                                        return taskInstance.status.taskStatus.portfolioName;
                                    },
                                    errors: function () {
                                        return taskInstance.status.taskStatus.details;
                                    },
                                    listPortfoliosHandler: () => ctx.listPortfoliosHandler.bind(ctx)

                                }
                            });
                    }
                });
            }
        }

        public setPrivate = function () {
            var ctx = this;
            ctx.isShared = false;
        }

        public setShared = function () {
            var ctx = this;
            ctx.isShared = true;
        }
    }



    function doIe9HackForInputFile(isIe9) {
        if (!isIe9) return;
        $(document).ready(function () {
            $('#portfolioFileContainer').remove();
            var inputString = "<input type='file' id='portfolioFile' name='portfolioFile' />";
            $('#fileHolder').append(inputString);
        });
    }

    function addFormForIe9Hack(isIe9) {
        if (!isIe9) return;
        $(document).ready(function () {
            var frmString = "<form id='testHack' method='POST' action='' enctype='multipart/form-data'>";
            $('#containerFormHack').wrap(frmString);
            $('#testHack').append("<input type='hidden' id='jsonData' name='data' value='' />");

            $('#testHack').submit(function (e) {
                var formObj = $(this);
                var formURL = formObj.attr("action");

                //generate a random id\
                var iframeId = 'unique' + (new Date().getTime());
                //create an empty iframe
                var iframe = $('<iframe src="javascript:false;" name="' + iframeId + '" />');

                //hide it
                iframe.hide();

                //set form target to iframe
                formObj.attr('target', iframeId);

                //Add iframe to body
                iframe.appendTo('body');
                iframe.load(function (e) {
                    var doc = getDocFromIframe(iframe[0]); //get iframe Document
                    var docRoot = doc.body ? doc.body : doc.documentElement;
                    var data = docRoot.innerHTML;
                    
                    //data is returned from server.
                });
            });
        });
    }



    function getDocFromIframe(frame) {
        var doc = null;

        // IE8 cascading access check
        try {
            if (frame.contentWindow) {
                doc = frame.contentWindow.document;
            }
        } catch (err) {
        }

        if (doc) { // successful getting content
            return doc;
        }

        try { // simply checking may throw in ie8 under ssl or mismatched protocol
            doc = frame.contentDocument ? frame.contentDocument : frame.document;
        } catch (err) {
            // last attempt
            doc = frame.document;
        }
        return doc;
    }




    // register controller with News Angular module
    angular.module(portfolioModuleName).controller('PortfolioUploadController',
        ['$rootScope', '$scope', '$q', '$http', '$location', 'PortfolioService', 'PortfolioCompanyService', 'notificationFactory', 'staticObjects',
            '$modal', '$modalInstance', 'LongRunningTaskManagerService', 'listPortfoliosHandler', PortfolioUploadController]);


} 
